package com.nulldev.util.web.nTubeExtensions.fuckAdvertising;

import java.io.InputStream;

import com.nulldev.util.JVM.JVM;
import com.nulldev.util.VariableAPI.RandomUtil;
import com.nulldev.util.VariableAPI.StringsUtil;
import com.nulldev.util.data.Variables;
import com.nulldev.util.data.variable;
import com.nulldev.util.data.Arrays.maps.FastMaps;
import com.nulldev.util.languages.json.uniapi.UniJsonValue;
import com.nulldev.util.logging.Logger;
import com.nulldev.util.logging.LoggerFactory;
import com.nulldev.util.web.HttpClient.HttpClient;
import com.nulldev.util.web.HttpClient.HttpResponse;
import com.nulldev.util.web.YouTubeExtractor.YouTubeExtractor;
import com.nulldev.util.web.YouTubeExtractor.advertising.YTEAdPlacement;
import com.nulldev.util.web.YouTubeExtractor.util.YouTubeExtractorUtil;

public class TotalAdvertiserDeath {

	private static final Logger log = LoggerFactory.getLogger();
	private static final String SDK_VERSION = "h.3.0";

	public static int invokeAdViewOrWatch(final YTEAdPlacement placement, final String videoID) {
		final variable<Integer> count = new variable<Integer>(0);
		switch (Variables.requireNonNullObject(placement, "placement").getType()) {
			case MIDROLL_AD: {
				final UniJsonValue obj = placement.getObject();
				final String adBreakUrlPre = obj.getString("getAdBreakUrl");
				/**
				 * cpn=[CPN] - ad id <br>
				 * &lact=[LACT] - ??? <br>
				 * &vis=[VIS] - visibility state (0=hidden, 1=visible)<br>
				 * &ad_block=[AD_BLOCK] - is adblock present <br>
				 * &tsla=[TSLA] <br>
				 * &bid=[BISCOTTI_ID] <br>
				 * &dt=[DT] - date as a UNIX timestamp <br>
				 * &flash=[FLASH] - is flash present (legacy) <br>
				 * &frm=[FRM] <br>
				 * &ca_type=[CA_TYPE] - unknown (youtube uses the "image" value) <br>
				 * &u_tz=[U_TZ] - timezone (in minutes) <br>
				 * &u_his=[U_HIS] - items in JS history <br>
				 * &u_java=[U_JAVA] - Is Java present (legacy) <br>
				 * &u_h=[U_H] - screen height <br>
				 * &u_w=[U_W] - screen width <br>
				 * &u_ah=[U_AH] - window height <br>
				 * &u_aw=[U_AW] - window width<br>
				 * &u_cd=[U_CD] - ??? (youtube uses a value of 24, might be content depth) <br>
				 * &u_nplug=[U_NPLUG] - plugin count (legacy) <br>
				 * &u_nmime=[U_NMIME] - plugin mimetype count (legacy)<br>
				 */
				final int fakeHeight = RandomUtil.randInt(390, 1000);
				final int fakeInnerHeight = RandomUtil.randInt(fakeHeight - 90, fakeHeight - 10);
				final int fakeWidth = RandomUtil.randInt(610, 1760);
				final int fakeInnerWidth = RandomUtil.randInt(fakeWidth - 90, fakeWidth - 10);
				final String adBreakUrl = StringsUtil.replaceAll(adBreakUrlPre, FastMaps.fixedUniMap(new Object[][]
					{
							/* Player Visibility status */
							{ "[VIS]", "1" },
							/* I miss Flash Player. */
							{ "[FLASH]", "0" },
							/* Unknown. */
							{ "[CA_TYPE]", "image" },
							{ "[CPN]", YouTubeExtractorUtil.makeDummyCPN() },
							/* lol, lmao even */
							{ "[AD_BLOCK]", "0" },
							/* Number of history elements */
							{ "[U_HIS]", String.valueOf(RandomUtil.randInt(0, 8)) },
							/* Display Parameters */
							{ "[PV_H]", String.valueOf(fakeHeight) },
							{ "[PV_W]", String.valueOf(fakeWidth) },
							{ "[U_H]", String.valueOf(fakeHeight) },
							{ "[U_W]", String.valueOf(fakeWidth) },
							{ "[U_AH]", String.valueOf(fakeInnerHeight) },
							{ "[U_AW]", String.valueOf(fakeInnerWidth) },
							/* Player Display Parameters */
							{ "[P_W]", String.valueOf(fakeInnerWidth - 30) },
							{ "[P_H]", String.valueOf(fakeInnerWidth - 20) },
							/* Timestamps */
							{ "[DT]", String.valueOf(System.currentTimeMillis()) },
							{ "[WT]", String.valueOf(System.currentTimeMillis()) },
							/* YT AD SDK. */
							{ "[SDKV]", SDK_VERSION },
							/* Connection Type */
							{ "[CONN]", "0" },
							/* Timezone in minutes */
							{ "[U_TZ]", "60" },
							/* WebGL */
							{ "[WGL]", "true" },
							/* Java Applets */
							{ "[U_JAVA]", "0" },
							/* Content-Depth (24 bits = XRGB888) */
							{ "[U_CD]", "24" },
							/* Taken with Chrome 115. */
							{ "[U_NPLUG]", "5" },
							{ "[U_NMIME]", "2" },
							/* YouTube provides "_lact" but I can't be bothered. */
							{ "[LACT]", String.valueOf(-1) } }));
				JVM.println(adBreakUrl);
				// FIXME: YouTube responds with a 410 GONE.
				break;
			}
			case PREROLL_OR_POSTROLL_BATCH: {
				final UniJsonValue obj = placement.getObject();
				/* TODO */
				obj.println();
				break;
			}
			case UI_PLACED_AD: {
				final UniJsonValue obj = placement.getObject();
				if (obj.contains("impressionPings")) {
					final UniJsonValue ping = obj.get("impressionPings").first();
					final String url = ping.getString("baseUrl");
					try {
						final HttpResponse<InputStream> req = HttpClient.getStream().url(url).headers(YouTubeExtractor.makeHeaders())
								.header("Referrer", "https://www.youtube.com/watch?v=" + videoID).header("Origin", "https://www.youtube.com/watch?v=" + videoID)
								.create();
						if (req.status() == 200)
							count.set(count.get() + 1);
						req.close();
					} catch (Exception e) {
						log.error("Failed to click on UI_PLACED_AD!", e);
					}
				} else {
					log.warn("Unknown UI_PLACED_AD object: " + obj);
				}
				break;
			}
			default:
				throw new UnsupportedOperationException("Unsupported type: " + placement.getType());
		}
		return count.get();
	}
}
